from django.conf import settings
from django.forms.fields import Field, EMPTY_VALUES
from django.forms.util import ValidationError
from django.utils.encoding import smart_unicode
from django.utils.translation import ugettext_lazy as _
import widgets


class AnswersField(Field):
    default_error_messages = {
        'min_answers': _(u'Ensure this value has at least %(min)d answers separated by newline (it has %(num)d).'),
        'duplicate_answers': _(u'Duplicate answers are not allowed.'),
    }

    def __init__(self, *args, **kwargs):
        self.min_answers = settings.OPINION_EXTRACTOR['min_answers_per_question']
        kwargs['widget'] = widgets.AnswersTextarea
        super(AnswersField, self).__init__(*args, **kwargs)

    def clean(self, value):
        """
        Validates against duplicate answers and the min_answers constraint.
        Returns a Unicode object in which unique answers are separated by newline.
        """
        super(AnswersField, self).clean(value)
        if value in EMPTY_VALUES:
            value = u''
        # If the value is not already a list - treat as string and split it into a list
        if not isinstance(value, (list, tuple)):
            value = smart_unicode(value).splitlines()
            
        # Filter out empty lines while stripping whitespace at the start and end of each line
        answers = filter(lambda x: len(x)>0, [s.strip() for s in value])
        num_answers = len(answers)
        if self.min_answers is not None and num_answers < self.min_answers:
            raise ValidationError(self.error_messages['min_answers'] % {
                'min': self.min_answers,
                'num': num_answers
            })
        if num_answers != len(set(answers)):
            raise ValidationError(self.error_messages['duplicate_answers'])
        return answers

    def widget_attrs(self, widget):
        return {'rows': '5'} # Likert scale is most commonly used and it has 5 choices
